package com.leizi.igym.controller.admin;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leizi.igym.BaseContext.UserThreadLocal;
import com.leizi.igym.constant.EmployeeConstant;
import com.leizi.igym.constant.FileConstant;
import com.leizi.igym.domain.Employee;
import com.leizi.igym.dto.EmployeeAddDTO;
import com.leizi.igym.dto.EmployeeDTO;
import com.leizi.igym.dto.EmployeePageQueryDTO;
import com.leizi.igym.dto.UploadFileDTO;
import com.leizi.igym.enums.FileUploadBizEnum;
import com.leizi.igym.enums.ReturnCodeEnum;
import com.leizi.igym.exception.BusinessException;
import com.leizi.igym.manager.CosManager;
import com.leizi.igym.pojo.ContextUser;
import com.leizi.igym.resp.PageResult;
import com.leizi.igym.resp.Result;
import com.leizi.igym.service.EmployeeService;
import com.leizi.igym.utils.COSUtils;
import com.leizi.igym.utils.ThrowUtils;
import com.leizi.igym.vo.EmployeeVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;

/**
 * @Author: leizi0110
 * @CreateTime: 2024-04-03  18:01
 * @Description:
 */

@RestController("adminEmployeeController")
@RequestMapping("/admin/employee")
@Tag(name = "管理端-员工相关接口")
@Slf4j
public class EmployeeController {

    @Resource
    private EmployeeService employeeService;
    @Resource
    private CosManager cosManager;


    @Operation(summary = "管理端：分页查询员工信息")
    @GetMapping("/page")
    public Result<PageResult> getEmpByPage(EmployeePageQueryDTO employeePageQueryDTO) {
        log.info("管理端正在分页查询员工信息，：查询参数：{}", employeePageQueryDTO);
        ThrowUtils.throwIf(Objects.isNull(employeePageQueryDTO), ReturnCodeEnum.PARAMS_ERROR);
        long current = employeePageQueryDTO.getCurrent();
        long size = employeePageQueryDTO.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 50, ReturnCodeEnum.PARAMS_ERROR);

        // 分页查询
        Page<Employee> page = employeeService.page(new Page<>(current, size),
                employeeService.getQueryWrapper(employeePageQueryDTO));
        List<EmployeeVO> employeeVOPage = employeeService.getEmployeeVOPage(page);

        // 封装到PageResult中
        PageResult pageResult = PageResult.builder().total(page.getTotal())
                .records(employeeVOPage)
                .build();
        return Result.ok(pageResult);
    }

    @Operation(summary = "管理端：根据id查询员工信息")
    @GetMapping("/{id}")
    public Result<EmployeeVO> getEmpById(@PathVariable("id") Long id) {
        log.info("管理端正在根据id查询员工信息，：查询员工id：{}", id);
        return Result.ok(employeeService.getEmpById(id));
    }

    @Operation(summary = "管理端：新增员工信息")
    @PostMapping
    public Result<Boolean> addEmp(@RequestBody EmployeeAddDTO addDTO) {
        log.info("管理端正在新增员工信息，：新增员工：{}", addDTO);
        ThrowUtils.throwIf(Objects.isNull(addDTO), ReturnCodeEnum.PARAMS_ERROR);
        Employee employee = new Employee();
        BeanUtils.copyProperties(addDTO, employee);
        // 若是管理端新增员工，默认就是审核过了
        employee.setIsIdentify(EmployeeConstant.IDENTIFIED);
        employee.setJoinTime(LocalDate.now());
        ThrowUtils.throwIf(!employeeService.save(employee), ReturnCodeEnum.SYSTEM_ERROR, "新增员工失败！");
        return Result.ok(true);
    }

    @Operation(summary = "管理端：删除员工信息")
    @DeleteMapping("{id}")
    public Result<Boolean> deleteEmpById(@PathVariable("id") Long id) {
        log.info("管理端正在删除员工信息，：删除员工id：{}", id);
        ThrowUtils.throwIf(Objects.isNull(id) || id < 0, ReturnCodeEnum.PARAMS_ERROR);
        ThrowUtils.throwIf(!employeeService.removeById(id), ReturnCodeEnum.SYSTEM_ERROR, "删除员工失败！");
        return Result.ok(true);
    }

    @Operation(summary = "管理端：批量删除员工信息")
    @DeleteMapping("batch")
    public Result<Boolean> deleteEmpBatch(@RequestBody List<Long> ids) {
        log.info("管理端正在删除员工信息，：删除员工id：{}", ids);
        ThrowUtils.throwIf(Objects.isNull(ids) || ids.size() == 0, ReturnCodeEnum.PARAMS_ERROR);
        ThrowUtils.throwIf(!employeeService.removeEmpBatch(ids), ReturnCodeEnum.SYSTEM_ERROR, "批量删除员工失败！");
        return Result.ok(true);
    }

    @Operation(summary = "管理端：上传头像")
    @PostMapping("upload")
    public Result<String> uploadAvatar(@RequestPart("avatar") MultipartFile multipartFile,
                                       UploadFileDTO uploadFileDTO) {
        log.info("管理端正在上传文件，上传类型：{}", uploadFileDTO);
        String biz = uploadFileDTO.getBiz();
        FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz);
        if (fileUploadBizEnum == null) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        // 获取当前管理员对象
        ContextUser admin = UserThreadLocal.get();
        ThrowUtils.throwIf(Objects.isNull(admin), ReturnCodeEnum.SYSTEM_ERROR);

        // 构造文件
        String uuid = UUID.randomUUID().toString(true);
        String filename = uuid + "-" + multipartFile.getOriginalFilename();
        String filepath = String.format("/%s/%s/%S", fileUploadBizEnum.getValue(), admin.getId(), filename);
        File file = null;
        try {
            // 上传文件
            file = File.createTempFile(filepath, null);
            multipartFile.transferTo(file);
            cosManager.putObject(filepath, file);
            // 返回可访问地址
            return Result.ok(FileConstant.COS_HOST + filepath);
        } catch (Exception e) {
            log.error("file upload error, filepath = " + filepath, e);
            throw new BusinessException(ReturnCodeEnum.SYSTEM_ERROR, "上传失败");
        } finally {
            if (file != null) {
                // 删除临时文件
                boolean delete = file.delete();
                if (!delete) {
                    log.error("file delete error, filepath = {}", filepath);
                }
            }
        }
    }

    @Operation(summary = "管理端：认证员工")
    @PutMapping("/{id}/{isIdentify}")
    public Result<Boolean> identify(@PathVariable("id") Long id,
                                    @PathVariable("isIdentify") Integer isIdentify) {
        log.info("管理端正在进行员工认证，员工id：{}", id);

        // 校验参数id是否合法
        ThrowUtils.throwIf(Objects.isNull(id) || id < 0, ReturnCodeEnum.PARAMS_ERROR, "员工id有误！");

        // 校验isIdentify参数是否合法
        ThrowUtils.throwIf(Objects.isNull(isIdentify) ||
                        !EmployeeConstant.EMP_IDENTIFY_LIST.contains(isIdentify)
                , ReturnCodeEnum.PARAMS_ERROR, "认证参数有误！");
        boolean result = employeeService.identifyEMp(id, isIdentify);
        return Result.ok(result);
    }

    @Operation(summary = "管理端：修改员工信息")
    @PutMapping("/{id}")
    public Result updateEmp(@PathVariable("id") Long id,
                            @RequestBody EmployeeDTO dto) {
        log.info("管理端正在修改员工信息，员工id为：{},修改信息为：{}", id, dto);
        if (Objects.isNull(dto) || id == null || id <= 0 || !id.equals(dto.getId())) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }
        EmployeeVO dbEmp = employeeService.getEmpById(id);
        String dbEmpAvatar = dbEmp.getAvatar();
        String avatar = dto.getAvatar();
        if ( dbEmpAvatar.contains(FileUploadBizEnum.EMP_AVATAR.getValue()) &&
                !avatar.equals(dbEmpAvatar)) {
            cosManager.deleteObject(COSUtils.parseFileNameForEmp(dbEmpAvatar));
        }
        Employee employee = new Employee();
        BeanUtils.copyProperties(dto, employee);
        return Result.ok(employeeService.updateEmpInAdmin(employee));

    }
}
